package com.csit.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.persistence.Transient;

import org.hibernate.criterion.DetachedCriteria;

import com.csit.bean.Pager;

/**
 * 
 * @Description: 
 * @Copyright: 福州骏华科技信息有限公司 (c)2012
 * @Created Date : 2012-3-28
 * @author longweier
 * @vesion 1.0
 */
public interface BaseDao<T, PK extends Serializable> {
	
	public final Integer DEFAULTPAGESIZE = 20;
	
	/**
	 * 
	 * @Description: 
	 * @Create: 2012-3-28 下午06:39:48
	 * @author longweier
	 * @update logs
	 * @param id 根据ID获取实体对象.
	 * @return 实体对象
	 * @throws Exception
	 */
	public T get(PK id);
	
	/**
	 * 
	 * @Description: 
	 * @Create: 2012-3-28 下午06:44:02
	 * @author longweier
	 * @update logs
	 * @param id 根据ID获取实体对象.
	 * @return  实体对象
	 * @throws Exception
	 */
	public T load(PK id);
	
	/**
	 * 
	 * @Description:  根据ID数组获取实体对象集合.
	 * @Create: 2012-3-28 下午06:44:21
	 * @author longweier
	 * @update logs
	 * @param ids   ID对象数组
	 * @return  实体对象集合
	 * @throws Exception
	 */
	public List<T> get(PK[] ids);
	
	/**
	 * 
	 * @Description:  根据属性名和属性值获取实体对象.
	 * @Create: 2012-3-28 下午06:44:52
	 * @author longweier
	 * @update logs
	 * @param propertyName 属性名称
	 * @param value  属性值
	 * @return  实体对象
	 * @throws Exception
	 */
	public T get(String propertyName, Object value);
	
	/**
	 * 
	 * @Description:  根据属性名和属性值获取实体对象集合.
	 * @Create: 2012-3-28 下午06:45:25
	 * @author longweier
	 * @update logs
	 * @param propertyName 属性名称
	 * @param value   属性值
	 * @return   实体对象集合
	 * @throws Exception
	 */
	public List<T> getList(String propertyName, Object value);
	
	/**
	 * 
	 * @Description:  根据多个属性名和属性值获取实体对象集合.
	 * @Create: 2012-3-28 下午06:45:25
	 * @author longweier
	 * @update logs
	 * @param propertyName 属性名称
	 * @param value   属性值
	 * @return   实体对象集合
	 * @throws Exception
	 */
	public List<T> getList(String[] propertiesName, Object value);
	
	/**
	 * 
	 * @Description: 获取所有实体对象集合.
	 * @Create: 2012-3-28 下午06:45:59
	 * @author longweier
	 * @update logs
	 * @return
	 * @throws Exception
	 */
	public List<T> getAll();
	
	/**
	 * 
	 * @Description:  获取所有实体对象总数.
	 * @Create: 2012-3-28 下午06:46:15
	 * @author longweier
	 * @update logs
	 * @return
	 * @throws Exception
	 */
	public Long getTotalCount();
	
	/**
	 * 
	 * @Description:  根据属性名、修改前后属性值判断在数据库中是否唯一(若新修改的值与原来值相等则直接返回true).
	 * @Create: 2012-3-28 下午06:46:34
	 * @author longweier
	 * @update logs
	 * @param propertyName  属性名称
	 * @param oldValue  修改前的属性值
	 * @param newValue  修改后的属性值
	 * @return
	 * @throws Exception
	 */
	public boolean isUnique(String propertyName, Object oldValue, Object newValue);
	
	/**
	 * 
	 * @Description:  根据多个属性名、修改前后属性值判断在数据库中是否唯一(若新修改的值与原来值相等则直接返回true).
	 * @Create: 2012-3-28 下午06:46:34
	 * @author longweier
	 * @update logs
	 * @param propertyName  属性名称
	 * @param oldValue  修改前的属性值
	 * @param newValue  修改后的属性值
	 * @return
	 * @throws Exception
	 */
	public boolean isUnique(String[] propertyName, Object oldValue, Object newValue);
	
	/**
	 * 
	 * @Description: 根据属性名判断数据是否已存在.
	 * @Create: 2012-3-28 下午06:47:32
	 * @author longweier
	 * @update logs
	 * @param propertyName  属性名称
	 * @param value    属性值
	 * @return
	 * @throws Exception
	 */
	public boolean isExist(String propertyName, Object value);
	
	/**
	 * 
	 * @Description: 根据多个属性名判断数据是否已存在.
	 * @Create: 2012-3-28 下午06:47:32
	 * @author longweier
	 * @update logs
	 * @param propertyName  属性名称
	 * @param value    属性值
	 * @return
	 * @throws Exception
	 */
	public boolean isExist(String[] propertiesName, Object value);
	/**
	 * 
	 * @Description:  保存实体对象.
	 * @Create: 2012-3-28 下午06:47:58
	 * @author longweier
	 * @update logs
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	@Transient
	public PK save(T entity);
	
	/**
	 * 
	 * @Description: 更新实体对象
	 * @Create: 2012-3-28 下午06:48:05
	 * @author longweier
	 * @update logs
	 * @param entity  实体对象
	 * @throws Exception
	 */
	public void update(T entity);
	
	/**
	 * 
	 * @Description: 根据某些属性进行更新数据
	 * @Create: 2012-3-29 下午10:45:40
	 * @author longweier
	 * @update logs
	 * @param propertys
	 * @param newEntity
	 * @param oldEntity
	 * @throws Exception
	 */
	public void updateProperty(String[] propertys, T newEntity, T oldEntity);
	
	/**
	 * 
	 * @Description: 删除实体对象
	 * @Create: 2012-3-28 下午06:48:22
	 * @author longweier
	 * @update logs
	 * @param entity  实体对象
	 * @throws Exception
	 */
	public void delete(T entity);
	
	/**
	 * 
	 * @Description: 根据ID删除对象
	 * @Create: 2012-3-28 下午06:49:05
	 * @author longweier
	 * @update logs
	 * @param id  实体主键
	 * @throws Exception
	 */
	public void delete(PK id);
	
	/**
	 * 
	 * @Description: 根据ID数组删除实体对象.
	 * @Create: 2012-3-28 下午06:49:39
	 * @author longweier
	 * @update logs
	 * @param ids  ID数组
	 * @throws Exception
	 */
	public void delete(PK[] ids);
	
	/**
	 * 
	 * @Description:  刷新session.
	 * @Create: 2012-3-28 下午06:49:59
	 * @author longweier
	 * @update logs
	 * @throws Exception
	 */
	public void flush();
	
	/**
	 * 
	 * @Description: 清除Session.
	 * @Create: 2012-3-28 下午06:50:13
	 * @author longweier
	 * @update logs
	 * @throws Exception
	 */
	public void clear();
	
	/**
	 * 
	 * @Description: 清除某一对象.
	 * @Create: 2012-3-28 下午06:50:30
	 * @author longweier
	 * @update logs
	 * @param object 清除对象.
	 * @throws Exception
	 */
	public void evict(Object object);

	/**
	 * 
	 * @Description: 合并
	 * @param
	 * @Create: 2012-8-6 下午05:40:52
	 * @author longweier
	 * @update logs
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	public void merge(T entity);
	/**
	 * 
	 * @Description:  根据Pager对象进行查询(提供分页、查找、排序功能).
	 * @Create: 2012-3-28 下午06:50:44
	 * @author longweier
	 * @update logs
	 * @param pager pager对象
	 * @param countTotal 是否需要统计总页数，可能用到ajax分页
	 * @return
	 * @throws Exception
	 */
	public Pager findByPager(Pager pager,Boolean countTotal);
	
	/**
	 * 
	 * @Description: 根据Pager和DetachedCriteria对象进行查询(提供分页、查找、排序功能).
	 * @Create: 2012-3-28 下午06:50:57
	 * @author longweier
	 * @update logs
	 * @param pager pager对象
	 * @param detachedCriteria detachedCriteria对象
	 * @param countTotal 是否需要统计总页数，可能用到ajax分页
	 * @return
	 * @throws Exception
	 */
	public Pager findByPager(Pager pager, DetachedCriteria detachedCriteria,Boolean countTotal);
	
	/**
	 * 
	 * @Description: 根据Pager 查询数组、查询值 进行查询(提供分页、查找、排序功能).
	 * @Create: 2012-3-29 下午11:05:49
	 * @author longweier
	 * @update logs
	 * @param pager pager对象
	 * @param propertys 需要查询的属性名称
	 * @param entity	查询的属性值
	 * @param countTotal 是否需要统计总页数，可能用到ajax分页
	 * @return
	 * @throws Exception
	 */
	public Pager findByPager(Pager pager,String[] propertys, T entity,Boolean countTotal);
	
	/**
	 * 
	 * @Description: 脱离Pager的分页查询,做到查询与统计的分开
	 * @param
	 * @Create: 2012-8-9 下午04:03:46
	 * @author longweier
	 * @update logs
	 * @param pageNumber 当前页数
	 * @param pageSize   每页显示多少条数据
	 * @param propertys  可供查询的属性
	 * @param entity     查询值
	 * @return
	 * @return
	 * @throws Exception
	 */
	public List<T> find(Integer pageNumber, Integer pageSize, String[] propertys, T entity);
	/**
	 * 
	 * @Description: 通过hql语句获取单个实体
	 * @Create: 2012-3-31 下午08:03:01
	 * @author longweier
	 * @update logs
	 * @param hql
	 * @return
	 * @throws Exception
	 */
	public Object getEntity(String hql);
	
	/**
	 * 
	 * @Description: 通过hql语句获取结果集
	 * @Create: 2012-3-31 下午08:03:54
	 * @author longweier
	 * @update logs
	 * @param hql
	 * @return
	 * @throws Exception
	 */
	public List<T> getEntityList(String hql);

	/**
	 *
	 * @param hql
	 * @param params
	 * @return
	 */
	public List<T> getEntityList(String hql,Object ... params);

	public List<T> getList(Map<String, Object> params);

}
